package com.naiterui.ehp.bs.im.repository.file;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

/**
 * 文件系统执行读取和写入等IO操作的实现类
 */
public final class IOHandler {

    private static final String DEFAULT_CHARSET = "UTF-8";

    private static final Logger LOGGER = LoggerFactory.getLogger(IOHandler.class);

    /**
     * 出指定目录下的全部文件集合
     */
    public static String[] listChildFiles(String dir) throws Exception {
        return new File(dir).list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return new File(dir, name).isFile();
            }
        });
    }

    /**
     * 读取指定文件的内容
     */
    public static String readFileContent(String filePath) throws Exception {
        try {
            return FileUtils.readFileToString(new File(filePath), DEFAULT_CHARSET);
        } catch (IOException e) {
            LOGGER.error("read file {}'s content failed.  exception is {}", filePath, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 创建目录
     */
    public static void createDirectory(String folderName) throws Exception {
        try {
            FileUtils.forceMkdir(new File(folderName));
        } catch (IOException e) {
            LOGGER.error("mkdir directory {} failed. exception is {}", folderName, e.getMessage(), e);
        }
    }

    /**
     * 判断文件或文件夹是否存在
     */
    public static boolean exists(String path) throws Exception {
        return new File(path).exists();
    }

    /**
     * 拷贝整个目录到目标目录
     */
    public static void copyDirectory(String srcDir, String destDir) throws Exception {
        try {
            FileUtils.copyDirectory(new File(srcDir), new File(destDir));
        } catch (IOException e) {
            LOGGER.error("copy directory {} to {} failed. exception is {}", srcDir, destDir, e.getMessage(), e);
        }
    }

    /**
     * 拷贝指定目录到目标目录
     */
    public static void copyDirectoryToDirectory(String srcDir, String destDir) throws Exception {
        try {
            FileUtils.copyDirectoryToDirectory(new File(srcDir), new File(destDir));
        } catch (IOException e) {
            LOGGER.error("copy directory {} to directory {} failed. exception is {}", srcDir, destDir, e.getMessage(), e);
        }
    }

    /**
     * 拷贝文件到指定目录
     */
    public static void copyFile(String srcDir, String destDir) throws Exception {
        try {
            FileUtils.copyFileToDirectory(new File(srcDir), new File(destDir));
        } catch (IOException e) {
            LOGGER.error("copy file {} to {} failed. exception is {}", srcDir, destDir, e.getMessage(), e);
        }
    }

    /**
     * 生成文件
     */
    public static void writeToFile(String dir, String content) throws Exception {
        try {
            FileUtils.writeStringToFile(new File(dir), content);
        } catch (IOException e) {
            LOGGER.error("write to file {} failed. excepton is {}", dir, e.getMessage(), e);
        }
    }

    /**
     * 删除目录
     */
    public static void removeDirectory(String dir) throws Exception {
        try {
            FileUtils.forceDelete(new File(dir));
        } catch (IOException e) {
            LOGGER.error("remove directory {} failed. excepton is {}", dir, e.getMessage(), e);
        }
    }

    /**
     * 获取指定目下所有文件的内容
     */
    public static List<String> getAllFileContents(String dir) throws Exception {

        // 返回值
        List<String> tplContents = new ArrayList<>();

        // 获取目录下的所有文件名
        String[] fileNames = listChildFiles(dir);

        // 拼接文件的完整路径获取文件内容
        for (int i = 0; i < fileNames.length; i++) {
            if (fileNames[i].indexOf(".html") == -1) {
                continue;
            }
            String fullPath = dir + "/" + fileNames[i];
            tplContents.add(readFileContent(fullPath));
        }

        return tplContents;
    }

    /**
     * 逐行读入文件内容
     */
    public static List<String> readLines(String filePath) throws Exception {
        try {
            return FileUtils.readLines(new File(filePath), DEFAULT_CHARSET);
        } catch (IOException e) {
            LOGGER.error("readLines from file {} failed. excepton is {}", filePath, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 向文件逐行写入
     */
    public static void writeLines(String filePath, List<String> lines) throws Exception {
        try {
            FileUtils.writeLines(new File(filePath), DEFAULT_CHARSET, lines);
        } catch (IOException e) {
            LOGGER.error("writeLines from file {} failed. excepton is {}", filePath, e.getMessage(), e);
        }
    }

    /**
     * 保存文件
     */
    public static void saveFile(String filePath, byte[] data) {
        try {
            FileUtils.writeByteArrayToFile(new File(filePath), data);
        } catch (IOException e) {
            LOGGER.error("save file {} failed. excepton is {}", filePath, e.getMessage(), e);
        }
    }
}
